#ifndef clox_memory_h
#define clox_memory_h

#include "common.h"
#include "object.h"

// 我们在堆上分配一个新数组，其大小刚好可以容纳字符串中的字符和末尾的结束符，使用这个底层宏来分配一个具有给定元素类型和数量的数组
#define ALLOCATE(type, count) \
    (type*) reallocate(NULL, 0, sizeof(type) * (count))
// 容量不足以2的倍数扩容,最小容量为8
#define GROW_CAPACITY(capacity) \
    ((capacity) < 8 ? 8 : (capacity) * 2)
#define FREE(type, pointer) reallocate(pointer, sizeof(type), 0)
#define GROW_ARRAY(type, pointer, oldCount, newCount) \
    (type*) reallocate(pointer, sizeof(type) * (oldCount), \
    sizeof(type) * (newCount))
// 对 reallocate() 调用的包装
#define FREE_ARRAY(type, pointer, oldCount) \
    reallocate(pointer, sizeof(type) * (oldCount), 0)
// 这个reallocate()函数是我们将在clox中用于所有动态内存管理的唯一函数——分配内存，
// 释放内存以及改变现有分配的大小。当我们稍后添加一个需要跟踪内存使用情况的垃圾收集器时，
// 通过单个函数路由所有这些操作是很重要的。
/**
 * @brief 内存分配操作说明表
 *
 * <table border="1">
 *   <tr>
 *     <th>oldSize</th>
 *     <th>newSize</th>
 *     <th>Operation</th>
 *   </tr>
 *   <tr>
 *     <td>0</td>
 *     <td>Non‑zero</td>
 *     <td>Allocate new block. 分配新块</td>
 *   </tr>
 *   <tr>
 *     <td>Non‑zero</td>
 *     <td>0</td>
 *     <td>Free allocation. 释放已分配内存</td>
 *   </tr>
 *   <tr>
 *     <td>Non‑zero</td>
 *     <td>Smaller than oldSize</td>
 *     <td>Shrink existing allocation. 收缩已分配内存</td>
 *   </tr>
 *   <tr>
 *     <td>Non‑zero</td>
 *     <td>Larger than oldSize</td>
 *     <td>Grow existing allocation. 增加已分配内存</td>
 *   </tr>
 * </table>
 *
 *
 * @param pointer
 * @param oldSize 当 oldSize 为0时，realloc() 等同于调用malloc()
 * @param newSize
 * @return
 */
void* reallocate(void* pointer, size_t oldSize, size_t newSize);
void freeObjects();
#endif